#include "ThreadPool.h"
#include <thread>
#include <iostream>

using namespace std;

ThreadPool::ThreadPool(size_t threadNum,size_t queCapacity)
    :_threadNum(threadNum)
    ,_threads()
    ,_queCapacity(queCapacity)
    ,_taskQue(_queCapacity)
    ,_isExit(false)
{

}

ThreadPool::~ThreadPool(){

}

void ThreadPool::start(){
    for(int idx = 0; idx < _threadNum; ++idx){
        _threads.push_back(thread(&ThreadPool::doTask,this));
    }
}

void ThreadPool::stop(){
    //Q1:任务没有执行完20次程序就退出？？？
    //A1:主线程执行stop太快
    //   需要让主线程等待任务队列为空再去回收
    while(!_taskQue.empty()){
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    _isExit = true;

    //Q2:20次任务执行完毕，但程序卡死无法退出？？？
    //A2:子线程在跳出while(!_isExit)循环之前，主线程还没有修改标志位_isExit为true
    //   子线程执行getTask，也就是_taskQue.pop，导致子线程睡眠
    //   所以需要将所有条件变量处于_notEmpty的子线程唤醒
    _taskQue.wakeup();

    for(auto & th : _threads){
        th.join();
    }
}

void ThreadPool::addTask(Task &&taskcb){
    if(taskcb){
        _taskQue.push(std::move(taskcb));
    }
}

Task ThreadPool::getTask(){
    return _taskQue.pop();
}

void ThreadPool::doTask(){
    while(!_isExit){
        Task taskcb = getTask();
        if(taskcb){
            taskcb();
        }else{
            cout << "nullptr == ptask" << endl;
        }
    }
}

